package com.xiaoshuidi.cloud.module.iot.service.impl.thirdPartImpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xiaoshuidi.cloud.module.iot.api.device.vo.AmmeterInfoResModel;
import com.xiaoshuidi.cloud.module.iot.api.device.vo.WaterMeterCommonResponseModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.DeviceGetDailyPowerResModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceRequestModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceResponseModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.PullThirdDeviceRequestModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenRequestModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenResponseModel;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbAccountDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDo;
import com.xiaoshuidi.cloud.module.iot.dal.repository.DeviceRepository;
import com.xiaoshuidi.cloud.module.iot.dal.repository.TbAccountRepository;
import com.xiaoshuidi.cloud.module.iot.enums.BrandEnum;
import com.xiaoshuidi.cloud.module.iot.enums.DeviceTypeEnum;
import com.xiaoshuidi.cloud.module.iot.enums.RedisTypeEnum;
import com.xiaoshuidi.cloud.module.iot.service.AbstractThirdInstanceService;
import com.xiaoshuidi.cloud.module.iot.service.CacheService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Sky
 * create 2019/04/10
 * email sky.li@ixiaoshuidi.com
 **/
@Service("yundingInstanceService")
public class YundingInstanceServiceImpl extends AbstractThirdInstanceService {

    private final static Logger LOGGER = LoggerFactory.getLogger(YundingInstanceServiceImpl.class);


    @Autowired
    private CacheService cacheService;
    @Autowired
    private TbAccountRepository tbAccountDataAccess;
    @Autowired
    private DeviceRepository deviceDataAccess;

    @Override
    public String getBrand() {
        return BrandEnum.YUNDING.getBrand();
    }


    /**
     * 云丁第三方电表id和roomid之间的关系
     * key:client_id
     * value:deviceArray
     */
    private static final Map<String, String> devicesCacheMap = Maps.newConcurrentMap();
    /**
     * 同步电表设备和房间的关系的锁
     */
    private Object devicesCacheLock = new Object();

    /**
     * 云丁固定请求头内容
     */
    private static final Map<String, String> header = Maps.newHashMap();

    static {
        header.put("Content-Type", "application/json");
        header.put("User-Agent", "ddingnet-3.0");
    }

    private static final int maxPageSize = 100;

    //云丁入住-租客姓名，手机号，退租时间
    private static final String tenant_name = "水滴管家";
    private static final String tenant_phone = "13915412194";
    //云丁退租统一时间：2030-01-01 00:00:00
    private static final Long tenant_recede_time = 1893427200000L;

    //云丁拉取设备
    @Value("${yunding.getDeviceList.url}")
    private String yundingGetDeviceListUrl;
    //云丁获取访问凭证
    @Value("${yunding.access_token.url}")
    private String yundingAccessTokenUrl;
    //云丁获取门锁信息URL
    @Value("${yunding.getLockInfo.url}")
    private String yundingGetLockInfoUrl;
    //云丁获取门锁动态密码
    @Value("${yunding.getDynamicPasswordPlaintext.url}")
    private String yundingGetDynamicPasswordPlaintextUrl;
    //云丁添加门锁在线密码
    @Value("${yunding.addPassword.url}")
    private String yundingAddPasswordUrl;
    //云丁修改门锁密码
    @Value("${yunding.updatePassword.url}")
    private String yundingUpdatePasswordUrl;
    //云丁删除门锁密码
    @Value("${yunding.deletePassword.url}")
    private String yundingDeletePasswordUrl;
    //云丁冻结门锁密码
    @Value("${yunding.frozenPassword.url}")
    private String yundingFrozenPasswordUrl;
    //云丁解冻门锁密码
    @Value("${yunding.unfrozenPassword.url}")
    private String yundingUnfrozenPasswordUrl;
    //云丁获取电表信息
    @Value("${yunding.getAmmeterInfo.url}")
    private String yundingAmmeterInfo;
    //云丁电表合闸
    @Value("${yunding.switchAmmeterOn.url}")
    private String yundingAmmeteron;
    //云丁电表跳闸
    @Value("${yunding.switchAmmeterOff.url}")
    private String yundingAmmeterOff;
    //云丁电表强制跳闸状态设置
    @Value("${yunding.setforcedState.url}")
    private String yundingforcedStateUrl;
    //云丁获取含公摊的最近一条用电记录(无公摊也可以查)
    @Value("${yunding.elemeterLastPowerHistoryWithPool.url}")
    private String yundingElemeterLastPowerHistoryWithPool;
    //云丁-添加租客
    @Value("${yunding.addTenant.url}")
    private String yundingAddTenant;
    //云丁-删除租客
    @Value("${yunding.deleteTenant.url}")
    private String yundingDeleteTenant;
    //云丁-获取水表信息
    @Value("${yunding.getWatermeterInfo.url}")
    private String yundingWatermeterInfo;
    //云丁-添加离线密码
    @Value("${yunding.addLxPassword.url}")
    private String yundingAddLxPasswordUrl;


    /**
     * 获取access_token
     *
     * @return
     */
    @Override
    public AccessTokenResponseModel getAccessToken(AccessTokenRequestModel accessTokenRequestModel) {
        AccessTokenResponseModel accessTokenResponseModel = new AccessTokenResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("client_id", accessTokenRequestModel.getAppId());
        bodyParam.put("client_secret", accessTokenRequestModel.getAppKey());
        LOGGER.info("云丁获取access_token，请求url:{},请求参数:{}", yundingAccessTokenUrl, bodyParam.toString());
        String result = HttpRequest.post(yundingAccessTokenUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁获取access_token,返回结果:{}", result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            Integer ErrNo = resultJsonObject.getInteger("ErrNo");
            if (0 == ErrNo) {
                accessTokenResponseModel = new AccessTokenResponseModel();
                //云丁访问凭证
                String access_token = resultJsonObject.getString("access_token");
                //云丁返回的失效时间（秒）
                Long expires_time = resultJsonObject.getLong("expires_time") - new Date().getTime() / 1000;
                accessTokenResponseModel.setAccessToken(access_token);
                //设置云丁访问凭证失效时间，比第三方少5分钟
                accessTokenResponseModel.setExpireTime(expires_time - 300);
            }

        }
        //第三方业务返回逻辑处理,返回获取的token
        return accessTokenResponseModel;
    }

    /**
     * 云丁拉取设备
     *
     * @param pullThirdDeviceRequestModel
     * @return
     */
    @Override
    public List<TbDeviceDo> getDevice(PullThirdDeviceRequestModel pullThirdDeviceRequestModel) {
        List<TbDeviceDo> tbDeviceDos = new ArrayList<>();
        String accessToken = pullThirdDeviceRequestModel.getAccessToken();
        String client_id = pullThirdDeviceRequestModel.getLoginName();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("offset", 0);
        bodyParam.put("count", maxPageSize);
        LOGGER.info("云丁拉取设备，请求url:{},请求参数:{}", yundingGetDeviceListUrl, bodyParam.toJSONString());
        String result = HttpRequest.get(yundingGetDeviceListUrl).form("access_token",accessToken).form("offset",0).form("count",maxPageSize).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁拉取设备，返回结果:{}", result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            Integer ErrNo = resultJsonObject.getInteger("ErrNo");
            if (0 == ErrNo) {
                JSONArray home_list = resultJsonObject.getJSONArray("home_list");
                if (CollUtil.isNotEmpty(home_list)) {
                    List<TbDeviceDo> existDevices = deviceDataAccess.getDeviceListByOneApiNo(pullThirdDeviceRequestModel.getTbAccountDo().getApiNo());
                    List<String> existDevicesUuid = existDevices.stream().map
                            (existDevice -> existDevice.getDeviceThirdNo()).collect(Collectors.toList());
                    for (Iterator<Object> homeIterator = home_list.iterator(); homeIterator.hasNext(); ) {
                        JSONObject homeInfo = (JSONObject) homeIterator.next();
                        JSONArray devices = homeInfo.getJSONArray("devices");
                        if (CollUtil.isNotEmpty(devices)) {
                            //云丁拉取过的电表设备不再处理
                            devices = devices.stream().filter(object ->
                                    !existDevicesUuid.contains(((JSONObject) object).getString("uuid"))).collect(Collectors.toCollection(JSONArray::new));
                            for (Iterator<Object> deviceIterator = devices.iterator(); deviceIterator.hasNext(); ) {
                                JSONObject deviceInfo = (JSONObject) deviceIterator.next();
                                TbDeviceDo tbDeviceDo = new TbDeviceDo();
                                //gateway 网关 lock 门锁（get_home_info接口中门锁不分内外门 锁） home_lock 外门锁 room_lock 内门锁
                                //- 12 - elemeter 电表 elecollector 采集器 water_gateway 水表网关 watermeter 水表
                                String type = deviceInfo.getString("type");
                                //设备唯一标识
                                String uuid = deviceInfo.getString("uuid");
                                //设备序列号
                                String sn = deviceInfo.getString("sn");
                                // 设备在线状态，1：在线；2：离线
                                Integer onoff = deviceInfo.getInteger("onoff");
                                tbDeviceDo.setDeviceThirdNo(uuid);
                                tbDeviceDo.setDeviceName(sn);
                                tbDeviceDo.setDeviceModel("YD");
                                tbDeviceDo.setUpdateTime(LocalDateTime.now());
                                tbDeviceDo.setReportTime(LocalDateTime.now());
                                tbDeviceDo.setOnlineStatus(onoff == 1 ? 1 : 0);
                                if (type.equals("lock") || type.equals("home_lock") || type.equals("room_lock")) {
                                    Double power = Optional.ofNullable(deviceInfo.getDouble("power")).orElse(0.0);
                                    tbDeviceDo.setBatteryLevel(power);
                                    tbDeviceDo.setDeviceType(DeviceTypeEnum.DOORLOCK.getCode());
                                } else if (type.equals("elemeter")) {
//                                    Double amount = Optional.ofNullable(deviceInfo.getDouble("amount")).orElseGet(() -> 0.0);
                                    //获取分摊读数和电表读数
                                    JSONObject lastAmountData = getElemeterLastPowerHistoryWithPool(uuid, accessToken);
                                    if (lastAmountData != null) {
                                        tbDeviceDo.setCurrentReading(lastAmountData.getDouble("consume_amount"));
                                        tbDeviceDo.setShareCurrentReading(lastAmountData.getDouble("pooling_amount"));
                                    } else {
                                        tbDeviceDo.setCurrentReading(0.0);
                                        tbDeviceDo.setShareCurrentReading(0.0);
                                    }
                                    tbDeviceDo.setPowerStatus(1);
                                    tbDeviceDo.setDeviceType(DeviceTypeEnum.AMMETER.getCode());
                                    //电表设备对应的房间id
                                    String room_id = deviceInfo.getString("room_id");
                                    devicesCacheMap.put(uuid, room_id);
                                } else if (type.equals("watermeter")) {
                                    Double amount = Optional.ofNullable(deviceInfo.getDouble("amount")).orElseGet(() -> 0.0);
                                    tbDeviceDo.setCurrentReading(amount);
                                    //水表类型，1：冷；2：热
                                    Integer meter_type = deviceInfo.getInteger("meter_type");
                                    if (1 == meter_type) {
                                        tbDeviceDo.setDeviceType(DeviceTypeEnum.COLD_WATERMETE_TYPE_ENUM.getCode());
                                    } else {
                                        tbDeviceDo.setDeviceType(DeviceTypeEnum.HOT_WATERMETE_TYPE_ENUM.getCode());
                                    }
                                } else {
                                    continue;
                                }
                                tbDeviceDos.add(tbDeviceDo);
                            }
                        }
                    }
                }
            }
        }
        return tbDeviceDos;
    }


    /**
     * 云丁设备初始化操作
     *
     * @param thirdDeviceList
     * @param pullThirdDeviceRequestModel
     * @return
     */
    @Override
    public List<TbDeviceDo> initializeDeviceInfo(List<TbDeviceDo> thirdDeviceList, PullThirdDeviceRequestModel pullThirdDeviceRequestModel) {
        return null;
    }

    /**
     * 云丁门锁添加密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel addDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        operateThirdDeviceResponseModel.setOperateResult(false);
        if(operateThirdDeviceRequestModel.getPasswordType().equals("1")){
            operateThirdDeviceResponseModel = addDoorLockZxPassword(operateThirdDeviceRequestModel);
        }else if(operateThirdDeviceRequestModel.getPasswordType().equals("6")){
            operateThirdDeviceResponseModel = addDoorLockLxPassword(operateThirdDeviceRequestModel);
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁门锁添加在线密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    private OperateThirdDeviceResponseModel addDoorLockZxPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        //商户自定义，对该密码的描述名称，必传参数
        bodyParam.put("name", operateThirdDeviceRequestModel.getUserName());
        bodyParam.put("phonenumber", operateThirdDeviceRequestModel.getMobile());
        //是否是超级管理员密码，0：否，1：是
        bodyParam.put("is_default", 0);
        bodyParam.put("password", operateThirdDeviceRequestModel.getPasswordContent());
        //云丁要求时间戳单位s
        bodyParam.put("permission_begin", operateThirdDeviceRequestModel.getPasswordStartTime() / 1000);
        bodyParam.put("permission_end", operateThirdDeviceRequestModel.getPasswordEndTime() / 1000);
        LOGGER.info("云丁设置门锁在线密码，请求url:{},请求参数:{}", yundingAddPasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingAddPasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁设置门锁在线密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            operateThirdDeviceResponseModel.setThirdPassId(resultJsonObject.getString("id"));
            //云丁操作门锁密码是异步
            operateThirdDeviceResponseModel.setPasswordStatus(4);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁门锁添加离线密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    private OperateThirdDeviceResponseModel addDoorLockLxPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        //商户自定义，对该密码的描述名称，必传参数
        bodyParam.put("name", operateThirdDeviceRequestModel.getUserName());
        bodyParam.put("phonenumber", operateThirdDeviceRequestModel.getMobile());
        //激活码类型。1：租客激活码密码，密码id范围为3025-3048,2：员工激活码密码，密码id范围为3001-3024,3：激活管理员密码，密码id为3000，
        // 多次调用增加激活管理员密码，新激活码在门锁上激活后，会覆盖旧密码。下发租客或员工激活码数量超过id范围后，如果之前有密码已失效，会使用失效密码的 id，否则下发失败。
        bodyParam.put("CMD", 1);
        //云丁密码有效期的结束时间时间戳，单位S。密码开始时间固定为请求调用时刻，无法指定。
        bodyParam.put("permission_end", operateThirdDeviceRequestModel.getPasswordEndTime() / 1000);
        LOGGER.info("云丁设置门锁离线密码，请求url:{},请求参数:{}", yundingAddLxPasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingAddLxPasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁设置门锁离线密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            operateThirdDeviceResponseModel.setThirdPassId(resultJsonObject.getString("id"));
            operateThirdDeviceResponseModel.setPasswordContent(resultJsonObject.getString("password"));
            operateThirdDeviceResponseModel.setPasswordCode(resultJsonObject.getString("code"));
            //云丁添加门锁离线密码是同步
            operateThirdDeviceResponseModel.setPasswordStatus(1);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁门锁获取动态密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel getDynamicDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        LOGGER.info("云丁获取门锁动态密码，请求url:{},请求参数:{}", yundingGetDynamicPasswordPlaintextUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.get(yundingGetDynamicPasswordPlaintextUrl).form("access_token",operateThirdDeviceRequestModel.getAccessToken()).form("uuid",operateThirdDeviceRequestModel.getDeviceThirdNo()).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁获取门锁动态密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            operateThirdDeviceResponseModel.setPasswordContent(resultJsonObject.getString("password"));
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁-刷新电表信息
     *
     * @param tbDeviceDo
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public AmmeterInfoResModel refreshAmmeterInfo(TbDeviceDo tbDeviceDo, OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        AmmeterInfoResModel ammeterInfoResModel = new AmmeterInfoResModel();
        String accessToken = operateThirdDeviceRequestModel.getAccessToken();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("uuid", tbDeviceDo.getDeviceThirdNo());
//        LOGGER.info("云丁获取电表基本信息get elemeter info,请求url:{},请求参数:{}", yundingAmmeterInfo, bodyParam.toJSONString());
        String result = HttpRequest.get(yundingAmmeterInfo).form("access_token",accessToken).form("uuid",tbDeviceDo.getDeviceThirdNo()).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
//        LOGGER.info("云丁获取电表基本信息get elemeter info,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        Integer errNo = resultJsonObject.getInteger("ErrNo");
        if (0 == errNo) {
            // 设备在线状态，1：在线；2：不在线
            Integer onoff_line = resultJsonObject.getInteger("onoff_line");
            // 电表合闸状态，-1：未知，1：合闸，2：跳闸
            Integer enable_state = resultJsonObject.getInteger("enable_state");
            //当前电表用电量，-1为未知
            Double consume_amount = resultJsonObject.getDouble("consume_amount");
            // 当前电表用电量刷新时间戳，单位MS
//            Long consume_amount_time = Optional.ofNullable(resultJsonObject.getLong("consume_amount_time")).orElseGet(() -> new Date().getTime());
//            ammeterInfoResModel.setReportTime(new Date(consume_amount_time));
            ammeterInfoResModel.setOnlineStatus(onoff_line == 1 ? 1 : 0);
            ammeterInfoResModel.setPowerStatus(enable_state == 1 ? 1 : 0);
            JSONObject lastAmountData = getElemeterLastPowerHistoryWithPool(tbDeviceDo.getDeviceThirdNo(), accessToken);
            if (lastAmountData != null) {
                ammeterInfoResModel.setReportTime(new Date(Optional.ofNullable(lastAmountData.getLong("time")).orElseGet(() -> new Date().getTime())));
                ammeterInfoResModel.setCurrentReading(lastAmountData.getDouble("consume_amount"));
                ammeterInfoResModel.setShareCurrentReading(lastAmountData.getDouble("pooling_amount"));
            }
        }
        return ammeterInfoResModel;
    }

    /**
     * 获取包含公摊的最近的一条电表用电记录，可用来计算房间\电表剩余电量；
     * 公摊的剩余电量计算公式： left = total_amount - consume_amount + charge_pooling_amount - pooling_amount
     *
     * @param uuid
     * @param accessToken
     * @return
     */
    public JSONObject getElemeterLastPowerHistoryWithPool(String uuid, String accessToken) {
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("uuid", uuid);
//        LOGGER.info("云丁获取含公摊的最近一条用电记录elemeter_last_power_history_with_pool,请求url:{},请求参数:{}", yundingElemeterLastPowerHistoryWithPool, bodyParam.toJSONString());
        String result = HttpRequest.get(yundingElemeterLastPowerHistoryWithPool).form("access_token",accessToken).form("uuid",uuid).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
//        LOGGER.info("云丁获取含公摊的最近一条用电记录elemeter_last_power_history_with_pool,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        Integer errNo = resultJsonObject.getInteger("ErrNo");
        JSONObject returnJson = null;
        if (0 == errNo) {
            returnJson = resultJsonObject.getJSONObject("history");
        }
        return returnJson;
    }

    @Override
    public List<DeviceGetDailyPowerResModel> getDailyPower(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    /**
     * 云丁门锁修改密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel updateDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        bodyParam.put("password_id", operateThirdDeviceRequestModel.getPasswordId());
        bodyParam.put("phonenumber", operateThirdDeviceRequestModel.getMobile());
        bodyParam.put("password", operateThirdDeviceRequestModel.getPasswordContent());
        //云丁要求时间戳单位s
        bodyParam.put("permission_begin", operateThirdDeviceRequestModel.getPasswordStartTime() / 1000);
        bodyParam.put("permission_end", operateThirdDeviceRequestModel.getPasswordEndTime() / 1000);
        LOGGER.info("云丁修改门锁密码，请求url:{},请求参数:{}", yundingUpdatePasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingUpdatePasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁修改门锁密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            //云丁操作门锁密码是异步
            operateThirdDeviceResponseModel.setPasswordStatus(4);
            //回调ID
            String serviceid = resultJsonObject.getString("serviceid");
            String cacheKey = RedisTypeEnum.SDIOT_DOORLOCK_ROLLBACK.getCode() + serviceid;
            String cacheValue = JSONObject.toJSONString(operateThirdDeviceRequestModel.getTbDoorlockPassword());
            cacheService.putString(cacheKey, cacheValue, 259200); //存入缓存三天
            LOGGER.info("云丁门锁设备修改门锁密码放入redis缓存,K:{},V:{}", cacheKey, cacheValue);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁冻结门锁密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel frozenDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        bodyParam.put("password_id", operateThirdDeviceRequestModel.getPasswordId());
        LOGGER.info("云丁冻结门锁密码，请求url:{},请求参数:{}", yundingFrozenPasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingFrozenPasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁冻结门锁密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            //云丁操作门锁密码是异步
            operateThirdDeviceResponseModel.setPasswordStatus(4);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁解冻门锁密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel unfrozenDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        bodyParam.put("password_id", operateThirdDeviceRequestModel.getPasswordId());
        LOGGER.info("云丁解冻门锁密码，请求url:{},请求参数:{}", yundingUnfrozenPasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingUnfrozenPasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁解冻门锁密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            //云丁操作门锁密码是异步
            operateThirdDeviceResponseModel.setPasswordStatus(4);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁-设置电表合闸
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel switchAmmeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        //云丁电表设置强制跳闸状态
        String setResult = setforcedState(operateThirdDeviceRequestModel.getAccessToken(), operateThirdDeviceRequestModel.getDeviceThirdNo(), 2);
        if (StringUtils.isNotBlank(setResult)) {
            JSONObject resultJsonObject = JSONObject.parseObject(setResult);
            Integer errNo = resultJsonObject.getInteger("ErrNo");
            if (0 != errNo) {
                operateThirdDeviceResponseModel.setOperateResult(false);
                operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
                return operateThirdDeviceResponseModel;
            }
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage("操作超时");
            return operateThirdDeviceResponseModel;
        }
        LOGGER.info("云丁电表合闸，请求url:{},请求参数:{}", yundingAmmeteron, bodyParam.toJSONString());
        String result = HttpRequest.post(yundingAmmeteron).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁电表合闸,返回结果:{}", result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            Integer errNo = resultJsonObject.getInteger("ErrNo");
            if (0 == errNo) {
                operateThirdDeviceResponseModel.setOperateResult(true);
            } else {
                operateThirdDeviceResponseModel.setOperateResult(false);
                operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
            }
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage("操作超时");
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁-设置电表跳闸
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel switchAmmeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        //云丁电表设置强制跳闸状态
        String setResult = setforcedState(operateThirdDeviceRequestModel.getAccessToken(), operateThirdDeviceRequestModel.getDeviceThirdNo(), 1);
        if (StringUtils.isNotBlank(setResult)) {
            JSONObject resultJsonObject = JSONObject.parseObject(setResult);
            Integer errNo = resultJsonObject.getInteger("ErrNo");
            if (0 != errNo) {
                operateThirdDeviceResponseModel.setOperateResult(false);
                operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
                return operateThirdDeviceResponseModel;
            }
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage("操作超时");
            return operateThirdDeviceResponseModel;
        }
        LOGGER.info("云丁电表跳闸，请求url:{},请求参数:{}", yundingAmmeterOff, bodyParam.toJSONString());
        String result = HttpRequest.post(yundingAmmeterOff).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁电表跳闸,返回结果:{}", result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            Integer errNo = resultJsonObject.getInteger("ErrNo");
            if (0 == errNo) {
                operateThirdDeviceResponseModel.setOperateResult(true);
            } else {
                operateThirdDeviceResponseModel.setOperateResult(false);
                if(5034 == errNo){
                    operateThirdDeviceResponseModel.setOperateMessage("操作太快,请稍后再试!");
                }else{
                    operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
                }
            }
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage("操作超时");
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     *
     * @param token  商户身份凭证
     * @param uuid 设备id
     * @param forceOpen 强制跳闸状态，1：开启；2：关闭
     * @return
     */
    public String setforcedState(String token,String uuid,Integer forceOpen){
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", token);
        bodyParam.put("uuid", uuid);
        bodyParam.put("force_open", forceOpen);
        LOGGER.info("云丁电表设置强制跳闸状态，请求url:{},请求参数:{}", yundingforcedStateUrl, bodyParam.toJSONString());
        String result = HttpRequest.post(yundingforcedStateUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁电表设置强制跳闸状态,返回结果:{}", result);
        return result;
    }

    /**
     * 云丁删除门锁密码
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel deleteDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNo());
        bodyParam.put("password_id", operateThirdDeviceRequestModel.getPasswordId());
        LOGGER.info("云丁删除门锁密码，请求url:{},请求参数:{}", yundingDeletePasswordUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingDeletePasswordUrl).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁删除门锁密码,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁-刷新水表
     *
     * @param waterMeterCommonResponseModel
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public WaterMeterCommonResponseModel refreshWatermeterInfo(WaterMeterCommonResponseModel waterMeterCommonResponseModel, OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        waterMeterCommonResponseModel.setOperateResult(false);
        String accessToken = operateThirdDeviceRequestModel.getAccessToken();
        String deviceThirdNo = waterMeterCommonResponseModel.getDeviceThirdNo();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("uuid", deviceThirdNo);
        LOGGER.info("云丁获取水表基本信息get_watermeter_info,请求url:{},请求参数:{}", yundingWatermeterInfo, bodyParam.toJSONString());
        String result = HttpRequest.get(yundingWatermeterInfo).form("access_token",accessToken).form("uuid",deviceThirdNo).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁获取水表基本信息get_watermeter_info,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        Integer errNo = resultJsonObject.getInteger("ErrNo");
        if (0 == errNo) {
            JSONObject info = resultJsonObject.getJSONObject("info");
            //在线情况，-1：初次绑定在线；1：在线；2：离线
            Integer onoff_line = info.getInteger("onoff");
            //水表读数
            Double amount = info.getDouble("amount");
            waterMeterCommonResponseModel.setOnlineStatus(onoff_line == 1 ? 1 : 0);
            waterMeterCommonResponseModel.setCurrentReading(amount);
            waterMeterCommonResponseModel.setOperateResult(true);
        }
        return waterMeterCommonResponseModel;
    }

    /**
     * 刷新门锁
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel getDoorLockStatus(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", operateThirdDeviceRequestModel.getAccessToken());
        bodyParam.put("uuid", operateThirdDeviceRequestModel.getDeviceThirdNoList().get(0));
        LOGGER.info("云丁获取门锁信息，请求url:{},请求参数:{}", yundingGetLockInfoUrl, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.get(yundingGetLockInfoUrl).form("access_token",operateThirdDeviceRequestModel.getAccessToken()).form("uuid",operateThirdDeviceRequestModel.getDeviceThirdNoList().get(0)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁获取门锁信息,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        String code = resultJsonObject.getString("ErrNo");
        if (code.equals("0")) {
            operateThirdDeviceResponseModel.setOperateResult(true);
            //云丁门锁状态：1在线，2离线
            operateThirdDeviceResponseModel.setOnlineStatus(resultJsonObject.getInteger("onoff_line") == 1 ? 1 : 0);
            operateThirdDeviceResponseModel.setBatteryLevel(resultJsonObject.getDouble("power"));
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    @Override
    public OperateThirdDeviceResponseModel setAmmeterPrice(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel setAmmeterPayment(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel setWaterMeterPrice(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel setWaterMeterPayment(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel chargeAmmeterFee(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    /**
     * 云丁-入住
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel stayAmmeter(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        operateThirdDeviceResponseModel.setOperateResult(false);
        String accessToken = operateThirdDeviceRequestModel.getAccessToken();
        String deviceThirdNo = operateThirdDeviceRequestModel.getDeviceThirdNo();
        String apiNo = operateThirdDeviceRequestModel.getApiNo();
        //云丁根据电表设备id获取roomid
        String room_id = getRoomIdByDevAmmeterId(deviceThirdNo, apiNo);
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("room_id", room_id);
        bodyParam.put("tenant_name", operateThirdDeviceRequestModel.getUserName());
        bodyParam.put("tenant_phone", operateThirdDeviceRequestModel.getUserMobile());
        bodyParam.put("start_time", new Date().getTime());
        bodyParam.put("end_time", tenant_recede_time);
        LOGGER.info("云丁电表入住,请求url:{},请求参数:{}", yundingAddTenant, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingAddTenant).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();

        LOGGER.info("云丁电表入住,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        Integer errNo = resultJsonObject.getInteger("ErrNo");
        if (0 == errNo) {
            operateThirdDeviceResponseModel.setOperateResult(true);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    /**
     * 云丁-退租
     *
     * @param operateThirdDeviceRequestModel
     * @return
     */
    @Override
    public OperateThirdDeviceResponseModel recedeAmmeter(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = new OperateThirdDeviceResponseModel();
        operateThirdDeviceResponseModel.setOperateResult(false);
        String accessToken = operateThirdDeviceRequestModel.getAccessToken();
        String deviceThirdNo = operateThirdDeviceRequestModel.getDeviceThirdNo();
        String apiNo = operateThirdDeviceRequestModel.getApiNo();
        //云丁根据电表设备id获取roomid
        String room_id = getRoomIdByDevAmmeterId(deviceThirdNo, apiNo);
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken);
        bodyParam.put("room_id", room_id);
        LOGGER.info("云丁电表退租,请求url:{},请求参数:{}", yundingDeleteTenant, JSONObject.toJSONString(bodyParam));
        String result = HttpRequest.post(yundingDeleteTenant).body(JSONUtil.toJsonStr(bodyParam)).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        LOGGER.info("云丁电表退租,返回结果:{}", result);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        Integer errNo = resultJsonObject.getInteger("ErrNo");
        if (0 == errNo) {
            operateThirdDeviceResponseModel.setOperateResult(true);
        } else {
            operateThirdDeviceResponseModel.setOperateResult(false);
            operateThirdDeviceResponseModel.setOperateMessage(resultJsonObject.getString("ErrMsg"));
        }
        return operateThirdDeviceResponseModel;
    }

    @Override
    public OperateThirdDeviceResponseModel getOpenLockRecordes(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchColdWaterMeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchHotWaterMeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchHotWaterMeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchColdWaterMeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    /**
     * 云丁根据电表设备id获取roomid
     *
     * @return
     */
    public String getRoomIdByDevAmmeterId(String devId, String apiNo) {
        String roomId = null;
        roomId = devicesCacheMap.get(devId);
        if (StringUtils.isBlank(roomId)) {
            synchronized (devicesCacheLock) {
                roomId = devicesCacheMap.get(devId);
                if (StringUtils.isBlank(roomId)) {
                    getUuidAndRoomIdRelation(apiNo);
                }
            }
        }
        return devicesCacheMap.get(devId);
    }

    /**
     * @param apiNo
     */
    public void getUuidAndRoomIdRelation(String apiNo) {
        TbAccountDo tbaccount = tbAccountDataAccess.getThirdApiByApiNo(apiNo);
        AccessTokenRequestModel accessTokenRequestModel = new AccessTokenRequestModel();
        accessTokenRequestModel.setAppId(tbaccount.getLoginName());
        accessTokenRequestModel.setAppKey(tbaccount.getLoginKey());
        AccessTokenResponseModel accessToken = getAccessToken(accessTokenRequestModel);
        //获取设备-刷新设备和room之间的关系
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("access_token", accessToken.getAccessToken());
        bodyParam.put("offset", 0);
        bodyParam.put("count", maxPageSize);
        String result = HttpRequest.get(yundingGetDeviceListUrl).form("access_token",accessToken.getAccessToken()).form("offset",0).form("count",maxPageSize).header("Content-Type", header.get("Content-Type"))
                .header("User-Agent", header.get("User-Agent")).execute().body();
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            Integer ErrNo = resultJsonObject.getInteger("ErrNo");
            if (0 == ErrNo) {
                JSONArray home_list = resultJsonObject.getJSONArray("home_list");
                if (CollUtil.isNotEmpty(home_list)) {
                    for (Iterator<Object> homeIterator = home_list.iterator(); homeIterator.hasNext(); ) {
                        JSONObject homeInfo = (JSONObject) homeIterator.next();
                        JSONArray devices = homeInfo.getJSONArray("devices");
                        if (CollUtil.isNotEmpty(devices)) {
                            for (Iterator<Object> deviceIterator = devices.iterator(); deviceIterator.hasNext(); ) {
                                JSONObject deviceInfo = (JSONObject) deviceIterator.next();
                                //gateway 网关 lock 门锁（get_home_info接口中门锁不分内外门 锁） home_lock 外门锁 room_lock 内门锁
                                //- 12 - elemeter 电表 elecollector 采集器 water_gateway 水表网关 watermeter 水表
                                String type = deviceInfo.getString("type");
                                if (type.equals("elemeter")) {
                                    //设备唯一标志
                                    String uuid = deviceInfo.getString("uuid");
                                    String room_id = deviceInfo.getString("room_id");
                                    devicesCacheMap.put(uuid, room_id);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
